home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1997 August / Walnut Creek CDROM.7z / VOL_400 / 420_01 / PI.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  15.2 KB  |  725 lines

  1. /*
  2. //    Pi.cc -- pi$@%U%)!<%^%C%H2hA|$r07$&(J
  3. //
  4. //        created    in 3/21/1993
  5. //        revised    in 2/13/1994
  6. */
  7.  
  8. #include    <stdio.h>
  9. #include    <stdlib.h>
  10. #include    "defs.h"
  11. #include    "Pi.h"
  12. #include    "Pic.h"
  13.  
  14. static unsigned char    ColorTable[16 + 1][16 + 1];
  15. static unsigned char    *ColorTable256;
  16. static int     PreviousColor;
  17. static int     RestLength;
  18. static unsigned char    *Screen2;
  19. static int     PiMode;
  20. static int     PiXRatio, PiYRatio;
  21. static int     PiPlaneSize;
  22. static int     (*ReadColor)();
  23. static void     (*WriteColor)( int Previous, int Color );
  24.  
  25. void    ExpandPi();
  26. int     PiReadLength();
  27. int     PiReadColor16();
  28. int     PiReadColor256();
  29. void    CompressPi();
  30. void    PiWriteLength( int n );
  31. void    PiWriteColor16( int Previous, int Color );
  32. void    PiWriteColor256( int Previous, int Color );
  33. int     Search( unsigned char *s1, int offset );
  34. void    ColorTableInitialize();
  35.  
  36. void    PiLoad()
  37. {
  38.     int     i, OldWidth, x, y;
  39.     int     Limit;
  40.  
  41.     if ( fp == NULL && (fp = fopen( File, "rb" )) == NULL )
  42.     error ("%s: No such file");
  43.     AllocateBuffer();
  44.     BitBufferLength = 0;
  45.     PicBitLoad (8);
  46.     if ( PicWord != 'P' )
  47.     error ("%s: Is not pi format");
  48.     PicBitLoad (8);
  49.     if ( PicWord != 'i' )
  50.     error ("%s: Is not pi format");
  51.     for ( i = 0; i < 16384; i++ ) {
  52.     PicBitLoad (8);
  53.     if ( PicWord == 0x1a )
  54.         break;
  55.     }
  56.     if ( i == 16384 )
  57.     error ("%s: Is not pi format");
  58.     for ( i = 0; i < 16384; i++ ) {
  59.     PicBitLoad (8);
  60.     if ( PicWord == 0 )
  61.         break;
  62.     }
  63.     if ( i == 16384 )
  64.     error ("%s: Is not pi format");
  65.     PicBitLoad (8);
  66.     if ( (PiMode = PicWord) & ~0x80 )
  67.     error ("%s: Unknown pi-mode");
  68.     PicBitLoad (8);
  69.     PiXRatio = PicWord;
  70.     PicBitLoad (8);
  71.     PiYRatio = PicWord;
  72.     if ( PiXRatio == 0 || PiYRatio == 0 )
  73.     PiXRatio = PiYRatio = 1;
  74.     PicBitLoad (8);
  75.     if ( (PiPlaneSize = PicWord) != 4 && PiPlaneSize != 8 )
  76.     error ("%s: Irregal place size");
  77.     if ( PiPlaneSize == 8 ) {
  78.     if ( (ColorTable256 = (unsigned char*)malloc (65536 + 16)) == NULL )
  79.         error ("%s: Insufficient memory");
  80.     }
  81.     else
  82.     ColorTable256 = NULL;
  83.     PicBitLoad (8);
  84.     PicBitLoad (8);
  85.     PicBitLoad (8);
  86.     PicBitLoad (8);
  87.     PicBitLoad (16);
  88.     for ( i = PicWord; i > 0; i-- )
  89.     PicBitLoad (8);
  90.     PicBitLoad (16);
  91.     Width = PicWord;
  92.     PicBitLoad (16);
  93.     Height = PicWord;
  94.     if ( Screen != NULL )
  95.     free (Screen);
  96.     if ( (Screen = (int16*)malloc ((Size = Width * Height * PiXRatio * PiYRatio * 2) + 64)) == NULL )
  97.     error ("%s: Insufficient memory");
  98.     if ( (Screen2 = (unsigned char*)malloc (Width * (Height + 2) + 64)) == NULL )
  99.     error ("%s: Insufficient memory");
  100.     for ( i = 0; i < Width * (Height + 2); i++ )
  101.     Screen2[i] = 0;
  102.     if ( PiMode & 0x80 ) {
  103.     if ( PiPlaneSize == 4 ) {
  104.         for ( i = 0; i < 16; i++ ) {
  105.         Red[i] = ((i & 2)? 1 : 0) * (1 + (i > 7)) * 16 - 1;
  106.         Green[i] = ((i & 4)? 1 : 0) * (1 + (i > 7)) * 16 - 1;
  107.         Blue[i] = ((i & 1)? 1 : 0) * (1 + (i > 7)) * 16 - 1;
  108.         }
  109.     }
  110.     else {
  111.         for ( i = 0; i < 256; i++ ) {
  112.         Red[i] = ((i >> 2) & 7) << 2;
  113.         Green[i] = (i >> 5) << 2;
  114.         Blue[i] = (i & 3) << 3;
  115.         }
  116.     }
  117.     }
  118.     else {
  119.     for ( i = 0; i < (1 << PiPlaneSize); i++ ) {
  120.         PicBitLoad (8);
  121.         Red[i] = PicWord >> 3;
  122.         PicBitLoad (8);
  123.         Green[i] = PicWord >> 3;
  124.         PicBitLoad (8);
  125.         Blue[i] = PicWord >> 3;
  126.     }
  127.     }
  128.     for ( i = 0; i < 256; i++ )
  129.     Palette[i] = (Red[i] << 5) | (Green[i] << 10) | Blue[i];
  130.     ColorTableInitialize();
  131.     ExpandPi();
  132.     Limit = Width * (Height + 2);
  133.     for ( i = Width * 2; i < Limit; i++ )
  134.     Screen[i - Width * 2] = Palette[Screen2[i]];
  135.     if ( PiXRatio != 1 || PiYRatio != 1 ) {
  136.     OldWidth = Width;
  137.     Width = Width * PiYRatio;
  138.     Height = Height * PiXRatio;
  139.     for ( y = Height - 1; y >= 0; y-- ) {
  140.         for ( x = Width - 1; x >= 0; x-- ) {
  141.         Screen[x + y * Width] = Screen[x / PiYRatio + (y / PiXRatio) * OldWidth];
  142.         }
  143.     }
  144.     }
  145.     if ( PiPlaneSize == 8 )
  146.     free (ColorTable256);
  147.     free (Screen2);
  148.     free (BitBuffer);
  149.     if ( fp != stdin )
  150.     fclose (fp);
  151.     if ( PiPlaneSize == 4 )
  152.     MaxColorGuaranteed = 16;
  153.     else
  154.     MaxColorGuaranteed = 256;
  155. }
  156.  
  157. void    PiSave()
  158. {
  159.     int     i, j;
  160.     int32    HalfSize, MaxColor;
  161.  
  162.     for ( i = 0; i < 16; i++ )
  163.     Palette[i] = -1;
  164.     MaxColor = 0;
  165.     HalfSize = Size / 2;
  166.     if ( (Screen2 = (unsigned char*)malloc (Width * (Height + 2) + 16)) == NULL )
  167.     error ("%s: Insufficient memory");
  168.     for ( i = 0; i < HalfSize; i++ ) {
  169.     for ( j = 0; j < MaxColor; j++ )
  170.         if ( Palette[j] == Screen[i] )
  171.         break;
  172.     Screen2[i + Width * 2] = j;
  173.     if ( j == MaxColor ) {
  174.         Palette[j] = Screen[i];
  175.         MaxColor++;
  176.         if ( MaxColor > 256 )
  177.         error ("%s: Too many colors for pi format");
  178.     }
  179.     }
  180.     MaxColorGuaranteed = MaxColor;
  181.     if ( fp == NULL && (fp = fopen( File, "wb" )) == NULL )
  182.     error ("%s: No such file");
  183.     for ( i = 0; i < MaxColor; i++ ) {
  184.     Red[i] = ((Palette[i] >> 5) & 31) << 3;
  185.     Green[i] = (Palette[i] >> 10) << 3;
  186.     Blue[i] = (Palette[i] & 31) << 3;
  187.     }
  188.     AllocateBufferForWriting();
  189.     BitBufferLength = BitBufferSize;
  190.     BitLength = 8;
  191.     BitBufferPointer = BitBuffer;
  192.     if ( MaxColor <= 16 ) {
  193.     ColorTable256 = NULL;
  194.     PiPlaneSize = 4;
  195.     ColorTableInitialize();
  196.     PicBitWrite( 8, 'P' );    /* id; */
  197.     PicBitWrite( 8, 'i' );
  198.     PicBitWrite( 8, 26 );    /* eof; */
  199.     PicBitWrite( 8, 0 );    /* separator; */
  200.     PicBitWrite( 8, 0 );    /* mode; */
  201.     PicBitWrite( 8, 0 );    /* ratio; */
  202.     PicBitWrite( 8, 0 );    /* ratio; */
  203.     PicBitWrite( 8, 4 );    /* depth; */
  204.     PicBitWrite( 8, '-' );    /* machine code; */
  205.     PicBitWrite( 8, '-' );    /* machine code; */
  206.     PicBitWrite( 8, '-' );    /* machine code; */
  207.     PicBitWrite( 8, '-' );    /* machine code; */
  208.     PicBitWrite( 16, 0 );    /* reserved size; */
  209.     PicBitWrite( 16, Width );
  210.     PicBitWrite( 16, Height );
  211.     for ( i = 0; i < 16; i++ ) {
  212.         PicBitWrite( 8, Red[i] );
  213.         PicBitWrite( 8, Green[i] );
  214.         PicBitWrite( 8, Blue[i] );
  215.     }
  216.     }
  217.     else {
  218.     if ( (ColorTable256 = (unsigned char*)malloc (65536 + 16)) == NULL )
  219.         error ("%s: Insufficient memory");
  220.     PiPlaneSize = 8;
  221.     ColorTableInitialize();
  222.     PicBitWrite( 8, 'P' );    /* id; */
  223.     PicBitWrite( 8, 'i' );
  224.     PicBitWrite( 8, 26 );    /* eof; */
  225.     PicBitWrite( 8, 0 );    /* separator; */
  226.     PicBitWrite( 8, 0 );    /* mode; */
  227.     PicBitWrite( 8, 0 );    /* ratio; */
  228.     PicBitWrite( 8, 0 );    /* ratio; */
  229.     PicBitWrite( 8, 8 );    /* depth; */
  230.     PicBitWrite( 8, '-' );    /* machine code; */
  231.     PicBitWrite( 8, '-' );    /* machine code; */
  232.     PicBitWrite( 8, '-' );    /* machine code; */
  233.     PicBitWrite( 8, '-' );    /* machine code; */ 
  234.     PicBitWrite( 16, 0 );    /* reserved size; */
  235.     PicBitWrite( 16, Width );
  236.     PicBitWrite( 16, Height );
  237.     for ( i = 0; i < 256; i++ ) {
  238.         PicBitWrite( 8, Red[i] );
  239.         PicBitWrite( 8, Green[i] );
  240.         PicBitWrite( 8, Blue[i] );
  241.     }
  242.     }
  243.     CompressPi();
  244.     PicBufferWriteFlush();
  245.     if ( PiPlaneSize == 8 )
  246.     free (ColorTable256);
  247.     free (Screen2);
  248.     free (BitBuffer);
  249.     if ( fp != stdout )
  250.     fclose (fp);
  251. }
  252.  
  253. void    ColorTableInitialize()
  254. {
  255.     int     i, j;
  256.  
  257.     if ( PiPlaneSize == 4 ) {
  258.     for ( j = 0; j < 16; j++ )
  259.         for ( i = 0; i < 16; i++ )
  260.         ColorTable[j][i] = (16 - i + j) & 15;
  261.     }
  262.     else {
  263.     for ( j = 0; j < 256; j++ )
  264.         for ( i = 0; i < 256; i++ )
  265.         ColorTable256[i + j * 256] = (256 - i + j);
  266.     }
  267. }
  268.  
  269. void    ExpandPi()
  270. {
  271.     int     i;
  272.     int     c0, c1, c2, c3;
  273.     unsigned char    *Screen3, *p;
  274.     int     RestSize;
  275.     int     PreviousPosition, Position, Length;
  276.  
  277.     if ( PiPlaneSize == 4 )
  278.     ReadColor = PiReadColor16;
  279.     else
  280.     ReadColor = PiReadColor256;
  281.     PreviousColor = 0;
  282.     c0 = ReadColor();
  283.     c1 = ReadColor();
  284.     Screen3 = Screen2;
  285.     for ( i = 0; i < Width; i++ ) {
  286.     *Screen3++ = c0;
  287.     *Screen3++ = c1;
  288.     }
  289.     RestSize = Width * Height / 2;
  290.     for ( PreviousPosition = -1;; ) {
  291.     PicBitLoad (2);
  292.     if ( (Position = PicWord) == 3 ) {
  293.         PicBitLoad (1);
  294.         Position += PicWord;
  295.     }
  296.     if ( PreviousPosition == Position ) {
  297.         PreviousPosition = -1;
  298.         PreviousColor = *(Screen3 - 1);
  299.         for ( ;; ) {
  300.         *Screen3++ = ReadColor();
  301.         *Screen3++ = ReadColor();
  302.         RestSize--;
  303.         PicBitLoad (1);
  304.         if ( PicWord == 0 )
  305.             break;
  306.         }
  307.         continue;
  308.     }
  309.     PreviousPosition = Position;
  310.     if ( (Length = PiReadLength()) <= 0 )
  311.         continue;
  312.     if ( (RestSize -= Length) < 0 ) {
  313.         Length += RestSize;
  314.         RestSize = 0;
  315.     }
  316. #define    MoveMem(Source,Destination,Size)    {\
  317.     unsigned char    *s, *d;\
  318.     int     Rest;\
  319.     s = Source;\
  320.     d = Destination;\
  321.     Rest = Size;\
  322.     while ( --Rest >= 0 ) {\
  323.     *d++ = *s++;\
  324.     *d++ = *s++;\
  325.     }\
  326.     Destination = d; }
  327.     switch (Position) {
  328.         case 4:
  329.         MoveMem( Screen3 - (Width + 1), Screen3, Length );
  330.         break;
  331.         case 3:
  332.                 MoveMem( Screen3 - (Width - 1), Screen3, Length );
  333.         break;
  334.         case 2:
  335.         MoveMem( Screen3 - (Width * 2), Screen3, Length );
  336.         break;
  337.         case 1:
  338.         MoveMem( Screen3 - Width, Screen3, Length );
  339.         break;
  340.         case 0:
  341.         p = Screen3 - 4;
  342.         c3 = *p++;
  343.         c2 = *p++;
  344.         c1 = *p++;
  345.         c0 = *p++;
  346.         Screen3 += Length + Length;
  347.         if ( c0 == c1 ) {
  348.             c2 = c0;
  349.             c3 = c1;
  350.         }
  351.         if ( Length == 1) {
  352.             *p++ = c3;
  353.             *p++ = c2;
  354.         }
  355.         else {
  356.             Length = (Length + 1) >> 1;
  357.             do {
  358.             int    n;
  359.             n = (Length > 16000) ? 16000 : Length;
  360.             Length -= n;
  361.             do {
  362.                 *p++ = c3;
  363.                 *p++ = c2;
  364.                 *p++ = c1;
  365.                 *p++ = c0;
  366.             } while (--n > 0);
  367.             } while (Length);
  368.         }
  369.         break;
  370.     }
  371.     if ( RestSize <= 0 )
  372.         break;
  373.     }
  374. }
  375.  
  376. int     PiReadLength()
  377. {
  378.     int     bits;
  379.     int     re;
  380.  
  381.     PicBitLoad (1);
  382.     if ( PicWord == 0 )
  383.     return 1;
  384.     for ( bits = 1;; bits++ ) {
  385.     PicBitLoad (1);
  386.     if ( PicWord == 0 )
  387.         break;
  388.     }
  389.     PicBitLoad (bits);
  390.     re = PicWord + (1 << bits);
  391.     return re;
  392. }
  393.  
  394. int     PiReadColor16()
  395. {
  396.     int     Color, k;
  397.     unsigned char    *p, *s, *d;
  398.  
  399.     PicBitLoad (1);
  400.     if ( PicWord != 0 ) {
  401.     PicBitLoad (1);
  402.     Color = PicWord;
  403.     goto Exit;
  404.     }
  405.     PicBitLoad (1);
  406.     if ( PicWord == 0 ) {
  407.     PicBitLoad (1);
  408.     Color = PicWord + 2;
  409.     goto Exit;
  410.     }
  411.     PicBitLoad (1);
  412.     if ( PicWord == 0 ) {
  413.     PicBitLoad (2);
  414.     Color = PicWord + 4;
  415.     goto Exit;
  416.     }
  417.     PicBitLoad (3);
  418.     Color = PicWord + 8;
  419.  Exit:
  420.     p = ColorTable[PreviousColor];
  421.     k = p[Color];
  422.     if (Color) {
  423.     s = p + Color;
  424.     d = s + 1;
  425.     while (Color--) *--d = *--s;
  426.     *p = (unsigned char)k;
  427.     }
  428.     return PreviousColor = k;
  429. }
  430.  
  431. int     PiReadColor256()
  432. {
  433.     int     Color, k;
  434.     unsigned char    *s, *d, *p;
  435.  
  436.     PicBitLoad (1);
  437.     if ( PicWord != 0 ) {
  438.     PicBitLoad (1);
  439.     Color = PicWord;
  440.     goto Exit;
  441.     }
  442.     PicBitLoad (1);
  443.     if ( PicWord == 0 ) {
  444.     PicBitLoad (1);
  445.     Color = PicWord + 2;
  446.     goto Exit;
  447.     }
  448.     PicBitLoad (1);
  449.     if ( PicWord == 0 ) {
  450.     PicBitLoad (2);
  451.     Color = PicWord + 4;
  452.     goto Exit;
  453.     }
  454.     PicBitLoad (1);
  455.     if ( PicWord == 0 ) {
  456.     PicBitLoad (3);
  457.     Color = PicWord + 8;
  458.     goto Exit;
  459.     }
  460.     PicBitLoad (1);
  461.     if ( PicWord == 0 ) {
  462.     PicBitLoad (4);
  463.     Color = PicWord + 16;
  464.     goto Exit;
  465.     }
  466.     PicBitLoad (1);
  467.     if ( PicWord == 0 ) {
  468.     PicBitLoad (5);
  469.     Color = PicWord + 32;
  470.     goto Exit;
  471.     }
  472.     PicBitLoad (1);
  473.     if ( PicWord == 0 ) {
  474.     PicBitLoad (6);
  475.     Color = PicWord + 64;
  476.     goto Exit;
  477.     }
  478.     PicBitLoad (7);
  479.     Color = PicWord + 128;
  480.  Exit:
  481.     p = ColorTable256 + PreviousColor * 256;
  482.     k = p[Color];
  483.     if (Color) {
  484.     s = p + Color;
  485.     d = s + 1;
  486.     while (Color--) *--d = *--s;
  487.     *p = k;
  488.     }
  489.     return PreviousColor = k;
  490. }
  491.  
  492. void    PiWriteColor16( int Previous, int Color )
  493. {
  494.     int     n, k, k0;
  495.     unsigned char    *p;
  496.  
  497.     p = ColorTable[Previous];
  498.     n = 0;
  499.     k = *p;
  500.     while ( Color != k && n++ < 16 ) {
  501.     k0 = *++p; *p = k; k = k0;
  502.     }
  503.     ColorTable[Previous][0] = Color;
  504.     if ( n < 2 ) {
  505.     PicBitWrite( 1, 1);
  506.     PicBitWrite( 1, n );
  507.     }
  508.     else if ( n < 4 ) {
  509.     PicBitWrite( 2, 0 );
  510.     PicBitWrite( 1, n - 2 );
  511.     }
  512.     else if ( n < 8 ) {
  513.     PicBitWrite( 3, 2 );
  514.     PicBitWrite( 2, n - 4 );
  515.     }
  516.     else {
  517.     PicBitWrite( 3, 3 );
  518.     PicBitWrite( 3, n - 8 );
  519.     }
  520. }
  521.  
  522. void    PiWriteColor256( int Previous, int Color )
  523. {
  524.     int     n, k, k0;
  525.     unsigned char    *p;
  526.  
  527.     p = ColorTable256 + Previous * 256;
  528.     n = 0;
  529.     k = *p;
  530.     while ( Color != k && n++ < 256 ) {
  531.     k0 = *++p; *p = k; k = k0;
  532.     }
  533.     *(ColorTable256 + Previous * 256) = Color;
  534.     if ( n < 2 ) {
  535.     PicBitWrite( 1, 1 );
  536.     PicBitWrite( 1, n );
  537.     }
  538.     else if ( n < 4 ) {
  539.     PicBitWrite( 2, 0 );
  540.     PicBitWrite( 1, n - 2 );
  541.     }
  542.     else if ( n < 8 ) {
  543.     PicBitWrite( 3, 2 );
  544.     PicBitWrite( 2, n - 4 );
  545.     }
  546.     else if ( n < 16 ) {
  547.     PicBitWrite( 4, 6 );
  548.     PicBitWrite( 3, n - 8 );
  549.     }
  550.     else if ( n < 32 ) {
  551.     PicBitWrite( 5, 14 );
  552.     PicBitWrite( 4, n - 16 );
  553.     }
  554.     else if ( n < 64 ) {
  555.     PicBitWrite( 6, 30 );
  556.     PicBitWrite( 5, n - 32 );
  557.     }
  558.     else if ( n < 128 ) {
  559.     PicBitWrite( 7, 62 );
  560.     PicBitWrite( 6, n - 64 );
  561.     }
  562.     else {
  563.     PicBitWrite( 7, 63 );
  564.     PicBitWrite( 7, n - 128 );
  565.     }
  566. }
  567.  
  568. int     Search( unsigned char *s1, int offset )
  569. {
  570.     int     m;
  571.     int     count;
  572.  
  573.     if  (*s1 != s1[offset]) return 0;
  574.     m = RestLength + RestLength;
  575.     count = 30000;
  576.     if ( count > m )
  577.     count = m;
  578.     m -= count;
  579.     while ( *s1 == s1[offset] ) {
  580.     if (!--count)
  581.         break;
  582.     s1++;
  583.     }
  584.     return RestLength - (m + count + 1) / 2;
  585. }
  586.  
  587. inline void    bitWriteTiny( int len, int data )
  588. {
  589.     while ( len-- ) {
  590.     PicBitWrite( 1, data >> len );
  591.     }
  592. }
  593.  
  594. void    PiWriteLength( int n )
  595. {
  596.     int     len, b;
  597.  
  598.     len = 0;
  599.     b = 2;
  600.     while ( n > b - 1 ) {
  601.     len++;
  602.     b <<= 1;
  603.     }
  604.     bitWriteTiny( len + 1, 0xfffffffe );
  605.     if ( len )
  606.     bitWriteTiny(len, n - b / 2);
  607. }
  608.  
  609. #define    calc0(p)    (((p)[Width2 - 2] == (p)[Width2 - 1]) \
  610.              ? Search((p) + Width2 - 2, 2) \
  611.              : Search((p) + Width2 - 4, 4))
  612. #define    calc1(p)    Search((p) + Width, Width)
  613. #define    calc2(p)    Search((p), Width2)
  614. #define    calc3(p)    Search((p) + Width + 1, Width - 1)
  615. #define    calc4(p)    Search((p) + Width - 1, Width + 1)
  616.  
  617. void    CompressPi()
  618. {
  619.     int     Width2, i, Position;
  620.     unsigned char    *pp;
  621.     int     l0, l1, l2, l3, l4;
  622.  
  623.     if ( PiPlaneSize == 4 )
  624.     WriteColor = PiWriteColor16;
  625.     else
  626.     WriteColor = PiWriteColor256;
  627.     Width2 = Width * 2;
  628.     for ( i = 0; i < Width2; i+=2 ) {
  629.     Screen2[i] = Screen2[Width2];
  630.     Screen2[i + 1] = Screen2[Width2 + 1];
  631.     }
  632.     pp = Screen2;
  633.     RestLength = Width * Height / 2;
  634.     WriteColor( 0, pp[Width2] );
  635.     WriteColor( pp[Width2], pp[Width2 + 1] );
  636.     Position = -1;
  637.     do {
  638.     l0 = l1 = l2 = l3 = l4 = 0;
  639.     if ( Position != 0 )
  640.         l0 = calc0(pp);
  641.     if ( Position != 1 )
  642.         l1 = calc1(pp);
  643.     if ( Position != 2 )
  644.         l2 = calc2(pp);
  645.     if ( Position != 3 )
  646.         l3 = calc3(pp);
  647.     if ( Position != 4 )
  648.         l4 = calc4(pp);
  649.     if (!(l0 + l1 + l2 + l3 + l4)) {
  650.         switch (Position) {
  651.             case 0:
  652.             PicBitWrite( 2, 0 );
  653.             break;
  654.         case 1:
  655.             PicBitWrite( 2, 1 );
  656.             break;
  657.         case 2:
  658.             PicBitWrite( 2, 2 );
  659.             break;
  660.         case 3:
  661.             PicBitWrite( 3, 6 );
  662.             break;
  663.         case 4:
  664.             PicBitWrite( 3, 7 );
  665.             break;
  666.         }
  667.         for ( ;; ) {
  668.         WriteColor( pp[Width2 - 1], pp[Width2 + 0] );
  669.         WriteColor( pp[Width2 + 0], pp[Width2 + 1] );
  670.         pp += 2;
  671.         if ( !--RestLength )
  672.             goto brk;
  673.         l0 = calc0(pp);
  674.         l1 = calc1(pp);
  675.         l2 = calc2(pp);
  676.         l3 = calc3(pp);
  677.         l4 = calc4(pp);
  678.         if ( l0 | l1 | l2 | l3 | l4 )
  679.             break;
  680.         PicBitWrite( 1, 1 );
  681.         }
  682.         PicBitWrite( 1, 0 );
  683.     }
  684.     Position = 0;
  685.     if ( l0 < l1 ) {
  686.         l0 = l1;
  687.         Position = 1;
  688.     }
  689.     if ( l0 < l2 ) {
  690.         l0 = l2;
  691.         Position = 2;
  692.     }
  693.     if ( l0 < l3 ) {
  694.         l0 = l3;
  695.         Position = 3;
  696.     }
  697.     if ( l0 < l4 ) {
  698.         l0 = l4;
  699.         Position = 4;
  700.     }
  701.     switch (Position) {
  702.         case 0:
  703.             PicBitWrite( 2, 0 );
  704.         break;
  705.         case 1:
  706.         PicBitWrite( 2, 1 );
  707.         break;
  708.         case 2:
  709.         PicBitWrite( 2, 2 );
  710.         break;
  711.         case 3:
  712.         PicBitWrite( 3, 6 );
  713.         break;
  714.         case 4:
  715.         PicBitWrite( 3, 7 );
  716.         break;
  717.     }
  718.     PiWriteLength (l0);
  719.     RestLength -= l0;
  720.     pp += l0 + l0;
  721.     } while ( RestLength > 0 );
  722.  brk:
  723.     PicBitWrite( 32, 0 );
  724. }
  725.